package ru.volgogradetzzz.math 
{
	/**
	 * @author Volgogradetzzz
	 */
	public class VVector2
	{
		//----------------------------------------------
		// Public fields
		//----------------------------------------------
		
		public static const ZERO:VVector2 = new VVector2();
		
		public var x:Number;
		public var y:Number;
		
		//----------------------------------------------
		// Constructor
		//----------------------------------------------
		
		public function VVector2(x:Number = 0, y:Number = 0) 
		{
			this.x = x;
			this.y = y;
		}
		
		//----------------------------------------------
		// Public methods
		//----------------------------------------------
		
		public function multiplyByMatrix(m:VMatrix2D):void
		{
			var tempX:Number = x;
			x = x * m.m11 + y * m.m21 + m.m31;
			y = tempX * m.m12 + y * m.m22 + m.m32;
		}
		
		public function multiplyByMatrixReturn(m:VMatrix2D):VVector2
		{
			return new VVector2(x * m.m11 + y * m.m21 + m.m31, x * m.m12 + y * m.m22 + m.m32);
		}
		
		public function multiplyByMatrixCopyTo(m:VMatrix2D, v:VVector2):void
		{
			v.x = x * m.m11 + y * m.m21 + m.m31;
			v.y = x * m.m12 + y * m.m22 + m.m32;
		}
		
		public function zero():void
		{
			x = y = 0;
		}
		
		public function negate():void
		{
			x = -x;
			y = -y;
		}
		
		public function add(v:VVector2):void
		{
			x += v.x;
			y += v.y;
		}
		
		public function addReturn(v:VVector2):VVector2
		{
			return new VVector2(x + v.x, y + v.y);
		}
		
		public function subtract(v:VVector2):void
		{
			x -= v.x;
			y -= v.y;
		}
		
		public function subtractReturn(v:VVector2):VVector2
		{
			return new VVector2(x - v.x, y - v.y);
		}
		
		public function scale(value:Number):void
		{
			x *= value;
			y *= value;
		}
		
		public function scaleReturn(value:Number):VVector2
		{
			return new VVector2(x * value, y * value);
		}
		
		public function magnitude():Number
		{
			return Math.sqrt(x * x + y * y);
		}
		
		public function squareMagnitude():Number
		{
			return x * x + y * y;
		}
		
		public function dot(v:VVector2):Number
		{
			return x * v.x + y * v.y;
		}
		
		public function cross(v:VVector2):Number
		{
			return x * v.y - y * v.x;
		}
		
		public function normal():VVector2
		{
			return new VVector2(y, -x);
		}
		
		public function dotNormal(v:VVector2):Number
		{
			return dot(v.normal());
		}
		
		public function normalize():void
		{
			var mSquare:Number = x * x + y * y;
			if (mSquare > 0)
			{
				var temp:Number = 1 / Math.sqrt(mSquare);
				x *= temp;
				y *= temp;
			}
			else
			{
				x = 1;
				y = 0;
			}
		}
		
		public function normalizeReturn():VVector2
		{
			var mSquare:Number = x * x + y * y;
			if (mSquare > 0)
			{
				var temp:Number = 1 / Math.sqrt(mSquare);
				return new VVector2(x * temp, y * temp);
			}
			
			return new VVector2(1, 0);
		}
		
		public function clone():VVector2
		{
			return new VVector2(x, y);
		}
		
		public function copyTo(v:VVector2):void{
			v.x = x;
			v.y = y;
		}
		
		public function copyFrom(v:VVector2):void{
			x = v.x;
			y = v.y;
		}
		
		public function toString():String
		{
			return 'x: ' + x + ', y: ' + y;
		}
	}
}